package com.yc.sole.code.generator;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 代码生成器
 *
 * @author yizuomin
 * @date 2022/11/22 19:28
 **/
@Slf4j
public class MyBatisPlusGenerator {

    private ConfigProperty configProperty;

    public MyBatisPlusGenerator(ConfigProperty configProperty) {
        this.configProperty = configProperty;
    }

    public void run() {
        try {
            generate(configProperty);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    private void generate(ConfigProperty config) {
        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(config.getOutFilePath());//自己的java目录
        globalConfig.setOpen(true);//是否打开输出目录
        globalConfig.setFileOverride(true);//是否覆盖已存在的文件
        globalConfig.setActiveRecord(true);
        globalConfig.setEnableCache(false); //XML文件 二级缓存
        globalConfig.setBaseResultMap(true);// xml文件 ResultMap
        globalConfig.setBaseColumnList(true);// xml columnList
        globalConfig.setAuthor(config.getAuthor());
        globalConfig.setDateType(DateType.ONLY_DATE);
        globalConfig.setIdType(IdType.ASSIGN_ID); //生成组件的id类型
        globalConfig.setSwagger2(config.isSwagger2());

        //数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(config.getDbType());
        dataSourceConfig.setTypeConvert(config.getDbTypeConvert());
        dataSourceConfig.setDriverName(config.getDbDriverName());
        dataSourceConfig.setUsername(config.getDbUsername());
        dataSourceConfig.setPassword(config.getDbPassword());
        dataSourceConfig.setUrl(config.getDbUrl());

        //策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);//表名生成策略
        strategyConfig.setEntityLombokModel(true);//采用lombok模型
        strategyConfig.setInclude(config.getTables());//需要生成的表名
        strategyConfig.setRestControllerStyle(true); // 生成RestController形式
        strategyConfig.setSuperEntityColumns("create_user_id", "create_time", "update_user_id", "update_time", "deleted");
        strategyConfig.setTablePrefix(config.getTablePrefix());
        //包名配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent(null);
        packageConfig.setMapper(config.getMapperPackagePath());
        packageConfig.setXml(config.getXmlPackagePath());
        packageConfig.setService(config.getServicePackagePath());
        packageConfig.setServiceImpl(config.getServiceImplPackagePath());
        packageConfig.setController(config.getControllerPackagePath());
        packageConfig.setEntity(config.getEntityPackagePath());

        // 自定义配置, 会被优先输出
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
                map.put("exceptionName", config.getExceptionName());
                map.put("packageDto", config.getDtoPackagePath());
                map.put("packageReq", config.getReqPackagePath());
                map.put("packageResp", config.getRespPackagePath());
                map.put("packageRepository", config.getRepositoryPackagePath());
                map.put("packageTest", config.getTestPackagePath());
                map.put("bizPackagePath", config.getBizPackagePath());
                map.put("moduleName", config.getModuleName());
                this.setMap(map);
            }
        };

        // 自定义生成Dto类
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig(config.getDtoTemplateLocation()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return config.getOutFilePath() + File.separator + config.getDtoPackagePath().replace(".", "/") + "/" + tableInfo.getEntityName() + "Dto.java";
            }
        });

        // biz
        focList.add(new FileOutConfig(config.getBizTemplateLocation()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return config.getOutFilePath() + File.separator + config.getBizPackagePath().replace(".", "/") + "/" + tableInfo.getEntityName() + "Biz.java";
            }
        });

        // repository
        focList.add(new FileOutConfig(config.getRepositoryTemplateLocation()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return config.getOutFilePath() + File.separator + config.getRepositoryPackagePath().replace(".", "/") + "/" + tableInfo.getEntityName() + "Repository.java";
            }
        });
        // req
        focList.add(new FileOutConfig(config.getReqTemplateLocation()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return config.getOutFilePath() + File.separator + config.getReqPackagePath().replace(".", "/") + "/" + tableInfo.getEntityName() + "Req.java";
            }
        });
        // 自定义生成resp类
        focList.add(new FileOutConfig(config.getRespTemplateLocation()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return config.getOutFilePath() + File.separator + config.getRespPackagePath().replace(".", "/") + "/" + tableInfo.getEntityName() + "Resp.java";
            }
        });
        cfg.setFileOutConfigList(focList);
        // 自定义生成QueryReq类
        focList.add(new FileOutConfig(config.getQueryReqTemplateLocation()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return config.getOutFilePath() + File.separator + config.getQueryReqPackagePath().replace(".", "/") + "/" + tableInfo.getEntityName() + "QueryReq.java";
            }
        });
        cfg.setFileOutConfigList(focList);

        // 模板配置
        TemplateConfig tc = new TemplateConfig();
        tc.setController(config.getControllerTemplateLocation());
        tc.setEntity(config.getEntityTemplateLocation());
        tc.setMapper(config.getMapperTemplateLocation());
        //tc.setXml(config.getXmlTemplateLocation());
        tc.setService(config.getServiceTemplateLocation());
        tc.setServiceImpl(config.getServiceImplTemplateLocation());

        //代码生成器
        new AutoGenerator()
                .setGlobalConfig(globalConfig)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                .setTemplate(tc)
                .setCfg(cfg).execute();
    }

}
